#include "../../include/Reactor/LRUCache.h"

template<class T1, class T2>
LRUCache<T1, T2>::LRUCache(int capacity)
    : m_capacity(capacity)
{}

template<class T1, class T2>
T2 LRUCache<T1, T2>::get(T1 key)
{
    if (m_ump.find(key) != m_ump.end())
    {
        m_lst.splice(m_lst.begin(), m_lst, m_ump[key]);
        m_ump[key] = m_lst.begin();
        return (*m_lst.begin()).second;
    }
    else
    {
        return T2{};
    }
}

template<class T1, class T2>
void LRUCache<T1, T2>::put(T1 key, T2 value)
{
    if (m_ump.find(key) != m_ump.end())
    {
        auto it1 = m_ump[key];
        m_lst.splice(m_lst.begin(), m_lst, it1);
        (*m_lst.begin()).second = value;
        m_ump[key] = m_lst.begin();
    }
    else
    {
        if (m_capacity == (int)m_lst.size())
        {
            m_ump.erase(m_lst.back().first);
            m_lst.pop_back();
        }
        m_lst.push_front({key, value});
        m_ump[key] = m_lst.begin();
    }
}

template<class T1, class T2>
vector<pair<T1, T2>> LRUCache<T1, T2>::getAll()
{
    vector<pair<T1, T2>> temp;
    for(auto & e : m_lst)
    {
        temp.push_back(e);
    }
    return temp;
}